package com.example.score.controller;

import com.example.score.common.Result;
import com.example.score.dto.KnowledgeScoreRateVo;
import com.example.score.entity.ClassInfo;
import com.example.score.entity.ExamBase;
import com.example.score.entity.ExamDetail;
import com.example.score.entity.input.ScoreAnalysisInput;
import com.example.score.entity.vo.ExamSubmitRateVo;
import com.example.score.mapper.ClassInfoMapper;
import com.example.score.mapper.ExamBaseMapper;
import com.example.score.mapper.ExamDetailMapper;
import com.example.score.service.ScoreAnalysisService;
import com.example.score.service.ScoreDistributionService;
import com.example.score.utils.ExcelGenerator;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/score")
@RequiredArgsConstructor
public class ScoreAnalysisController {

    private static final Logger log = LoggerFactory.getLogger(ScoreAnalysisController.class);

    private final ScoreAnalysisService scoreAnalysisService;
    private final ScoreDistributionService scoreDistributionService;
    private final ExamDetailMapper examDetailMapper;
    private final ClassInfoMapper classInfoMapper;
    private final ExamBaseMapper examBaseMapper;


    /**
     * 1.1 成绩概览表
     * 满分/最高分/平均分/优秀率/及格率/中位数/标准差
     */
    @GetMapping("/overview/{examId}")
    public Result<?> getScoreOverview(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            Map<String, Object> data = scoreAnalysisService.calculateScoreOverview(examId, classId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取成绩概览失败: {}", e.getMessage(), e);
            return Result.error("获取成绩概览失败: " + e.getMessage());
        }
    }

    /**
     * 1.2 作业得分表
     * 班级/考号/姓名/学科-日期/总分/客观题/主观题等详细信息
     */
    @GetMapping("/score-details/{examId}")
    public Result<List<Map<String, Object>>> getScoreDetails(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        log.info("接收到作业得分表请求 - examId: {}, classId: {}", examId, classId);
        try {
            List<Map<String, Object>> data = scoreAnalysisService.calculateScoreDetails(examId, classId);
            log.info("成功获取作业得分表数据 - 记录数: {}", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取作业得分表失败", e);
            return Result.error("获取作业得分表失败: " + e.getMessage());
        }
    }

    /**
     * 1.2.1 下载成绩单
     * 班级/考号/姓名/学科-日期/总分/客观题/主观题等详细信息
     */
    @GetMapping("/score-details/excel/{examId}")
    public Result<?> scoreDetailsExcel(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        log.info("接收到作业得分表请求 - examId: {}, classId: {}", examId, classId);
        try {
            ExamBase examBase = examBaseMapper.selectByExamId(examId);
            if(examBase == null) {
                throw new RuntimeException("未找到考试信息");
            }
            ExamDetail examDetail = examDetailMapper.selectByExamId(examId);
            if(examDetail == null) {
                throw new RuntimeException("未找到考试信息");
            }
            ClassInfo classInfo = new ClassInfo();
            if(!ObjectUtils.isEmpty(classId)) {
                classInfo = classInfoMapper.selectByClassId(classId, examDetail.getId());
                if(classInfo == null){
                    throw new Exception("未找到班级，班级id：" + classId);
                }
            }
            // 获取学生提交记录
            List<Map<String, Object>> data = scoreAnalysisService.calculateScoreDetailsExcel(examDetail, classInfo);
            String path = scoreAnalysisService.excel(data, examBase, examDetail, classInfo, 0);
            log.info("成功下载得分表Excel :{}", path);
            return Result.success(path);
        } catch (Exception e) {
            log.error("获取作业得分表失败", e);
            return Result.error("获取作业得分表失败: " + e.getMessage());
        }
    }

    /**
     * 1.3 上升/下降学生分析
     * 分析学生成绩和排名的波动情况
     */
    @GetMapping("/rank-change/{examId}")
    public Result<?> getRankChange(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            log.info("获取成绩波动分析 - examId: {}, classId: {}", examId, classId);
            Map<String, Object> data = scoreAnalysisService.calculateRankChange(classId, examId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取成绩波动分析失败: {}", e.getMessage(), e);
            return Result.error("获取成绩波动分析失败: " + e.getMessage());
        }
    }

    /**
     * 1.4 高频错题表
     * 得分率≤40%的题目统计
     */
    @GetMapping("/error-questions/{examId}")
    public Result<List<Map<String, Object>>> getErrorQuestions(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId,
            @RequestParam(required = false, defaultValue = "0") Integer startRate,
            @RequestParam(required = false, defaultValue = "60")  Integer endRate) {
        try {
            if (examId == null || examId <= 0) {
                return Result.error("考试ID不能为空");
            }
            List<Map<String, Object>> data = scoreAnalysisService.calculateErrorQuestions(examId, classId, startRate, endRate);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取高频错题统计失败: {}", e.getMessage(), e);
            return Result.error("获取高频错题统计失败: " + e.getMessage());
        }
    }


    /**
     * 2.1 分数段分布图表
     */
    @GetMapping("/score-distribution/{examId}")
    public Result<?> getScoreDistribution(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId,
            @RequestParam(defaultValue = "20") Integer segment) {
        try {
            List<Map<String, Object>> data = scoreDistributionService.calculateScoreDistribution(examId, classId, segment);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取分数段分布失败: {}", e.getMessage(), e);
            return Result.error("获取分数段分布失败: " + e.getMessage());
        }
    }

    /**
     * 2.2 箱线图数据
     */
    @GetMapping("/box-plot/{examId}")
    public Result<?> getBoxPlot(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            double[] data = scoreDistributionService.calculateBoxPlotData(examId, classId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取箱线图数据失败: {}", e.getMessage(), e);
            return Result.error("获取箱线图数据失败: " + e.getMessage());
        }
    }


    /**
     * 2.2.3 空白率分布
     */
    @GetMapping("/blank-rate/{examId}")
    public Result<?> getBlankRate(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            List<Map<String, Object>> data = scoreDistributionService.calculateBlankRate(examId, classId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取空白率分布失败: {}", e.getMessage(), e);
            return Result.error("获取空白率分布失败: " + e.getMessage());
        }
    }

    /**
     * 3.2 两分五率
     */
    @PostMapping("/score-rates")
    public Result<?> getScoreRates(@RequestBody ScoreAnalysisInput input) {
        try {
            List<Map<String, Object>> data = scoreDistributionService.calculateScoreRates(input.getExamId(), input.getClassId(),input.getTeacherId());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取两分五率失败: {}", e.getMessage(), e);
            return Result.error("获取两分五率失败: " + e.getMessage());
        }
    }

    /**
     * 2.2.5 学优生/学困生分布
     */
    @GetMapping("/student-distribution/{examId}")
    public Result<?> getStudentDistribution(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            List<Map<String, Object>> data = scoreDistributionService.calculateStudentDistribution(examId, classId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取学生分布失败: {}", e.getMessage(), e);
            return Result.error("获取学生分布失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.1获取作业质量
     */
    @GetMapping("/homework-quality/{examId}")
    public Result<?> getHomeworkQuality(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            log.info("获取作业质量数据 - examId: {}, classId: {}", examId, classId);
            Map<String, Object> data = scoreAnalysisService.calculateHomeworkQuality(examId, classId);
            log.info("作业质量数据计算完成: {}", data);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取作业质量失败: {}", e.getMessage(), e);
            return Result.error("获取作业质量失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.2试题得分率
     */
    @GetMapping("/question-score-rates/{examId}")
    public Result<?> getQuestionScoreRates(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            log.info("获取试题得分率数据 - examId: {}, classId: {}", examId, classId);
            List<Map<String, Object>> data = scoreAnalysisService.calculateQuestionScoreRates(examId, classId);
            log.info("试题得分率数据计算完成，共 {} 条记录", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取试题得分率失败: {}", e.getMessage(), e);
            return Result.error("获取试题得分率失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.3小题分析
     */
    @GetMapping("/question-analysis/{examId}")
    public Result<?> getQuestionAnalysis(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            log.info("获取小题分析数据 - examId: {}, classId: {}", examId, classId);
            List<Map<String, Object>> data = scoreAnalysisService.calculateQuestionAnalysis(examId, classId);
            log.info("小题分析数据计算完成，共 {} 条记录", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取小题分析失败: {}", e.getMessage(), e);
            return Result.error("获取小题分析失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.4知识点得分率
     */
    @GetMapping("/knowledge-score-rates/{examId}")
    public Result<?> getKnowledgeScoreRates(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            log.info("获取知识点得分率数据 - examId: {}, classId: {}", examId, classId);
            List<Map<String, Object>> data = scoreAnalysisService.calculateKnowledgeScoreRates(examId, classId);
            log.info("知识点得分率数据计算完成，共 {} 条记录", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取知识点得分率失败: {}", e.getMessage(), e);
            return Result.error("获取知识点得分率失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.3.1客观题作答分布
     */
    @GetMapping("/objective-answer-distribution/{examId}")
    public Result<?> getObjectiveAnswerDistribution(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            List<Map<String, Object>> data = scoreAnalysisService.calculateObjectiveAnswerDistribution(examId, classId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取客观题作答分布失败: {}", e.getMessage(), e);
            return Result.error("获取客观题作答分布失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.3.2主观题作答分布
     */
    @GetMapping("/subjective-answer-distribution/{examId}")
    public Result<?> getSubjectiveAnswerDistribution(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            List<Map<String, Object>> data = scoreAnalysisService.calculateSubjectiveAnswerDistribution(examId, classId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取主观题作答分布失败: {}", e.getMessage(), e);
            return Result.error("获取主观题作答分布失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.4 错题分布
     */
    @GetMapping("/error-distribution/{examId}")
    public Result<?> getErrorDistribution(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId,
            @RequestParam(required = false, defaultValue = "0") Integer isSubjective) {
        try {
            Map<String, Object> data = scoreAnalysisService.calculateErrorDistribution(examId, classId, isSubjective);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取错题分布失败: {}", e.getMessage(), e);
            return Result.error("获取错题分布失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.4 错题分布_详情
     */
    @GetMapping("/error-distribution-detail/{examId}")
    public Result<?> getErrorDistributionDetail(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId,
            @RequestParam Long questionId) {
        try {
            Map<String, Object> data = scoreAnalysisService.calculateErrorDistributionDetail(examId, classId, questionId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取错题分布详情失败: {}", e.getMessage(), e);
            return Result.error("获取错题分布详情失败: " + e.getMessage());
        }
    }
    // 错题分布_详情 获取所有试题得分情况
    @GetMapping("/error-distribution-detail/list/{examId}")
    public Result<?> getErrorDistributionDetailList(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId,
            @RequestParam(required = false) Integer rateLeft, @RequestParam(required = false) Integer rateRight,  @RequestParam(required = false) String questionTypeName) {
        try {
            List<Map<String, Object>> data = scoreAnalysisService.calculateErrorDistributionDetailList(examId, classId, rateLeft, rateRight, questionTypeName);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取错题分布详情失败: {}", e.getMessage(), e);
            return Result.error("获取错题分布详情失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.5 获取双向细目表
     */
    @GetMapping("/question-matrix/{examId}")
    public Result<?> getQuestionMatrix(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId) {
        try {
            List<Map<String, Object>> data = scoreAnalysisService.calculateQuestionMatrix(examId, classId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取双向细目表失败: {}", e.getMessage(), e);
            return Result.error("获取双向细目表失败: " + e.getMessage());
        }
    }

    /**
     * 获取作业汇总数据
     */
    @GetMapping("/homework-summary/{examId}")
    public Result<?> getHomeworkSummary(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId,
            @RequestParam(defaultValue = "week") String summaryType) {
        try {
            log.info("获取作业汇总数据 - examId: {}, classId: {}, type: {}", examId, classId, summaryType);
            List<Map<String, Object>> data = scoreAnalysisService.calculateHomeworkSummary(examId, classId, summaryType);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取作业汇总数据失败: {}", e.getMessage(), e);
            return Result.error("获取作业汇总数据失败: " + e.getMessage());
        }
    }


    /*********************************************学生端***********************************************/
    /**
     * 2.3.1 学生成绩单
     */
    @GetMapping("/student/transcript/{examId}")
    public Result<?> studentTranscript(
            @PathVariable Long examId,
            @RequestParam(required = false) String studentId) {
        try {
            log.info("获取作业汇总数据 - examId: {}, classId: {}", examId, studentId);
            Map<String, Object> data = scoreAnalysisService.calculateStudentHomeworkOverview(examId, studentId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取作业汇总数据失败: {}", e.getMessage(), e);
            return Result.error("获取作业汇总数据失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.2 获取班级成绩定位数据
     * 返回学生分数、班排名、班级/全体均分及离均差
     */
    @GetMapping("/student/class-position/{examId}")
    public Result<?> getClassPosition(
            @PathVariable Long examId,
            @RequestParam(required = false) Long classId,
            @RequestParam(required = false) String studentId) {
        try {
            log.info("获取班级成绩定位数据 - examId: {}, classId: {}, studentId: {}", examId, classId, studentId);
            Map<String, Object> data = scoreAnalysisService.calculateClassPosition(examId, classId, studentId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取班级成绩定位数据失败: {}", e.getMessage(), e);
            return Result.error("获取班级成绩定位数据失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.3获取学生小题分（可查看有痕）
     */
    @GetMapping("/student/question-scores/{examId}")
    public Result<?> getQuestionScores(
            @PathVariable Long examId,
            @RequestParam String studentId) {
        try {
            log.info("获取学生小题分数据 - examId: {}, studentId: {}", examId, studentId);
            Map<String, Object> data = scoreAnalysisService.getQuestionScores(examId, studentId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取学生小题分数据失败: {}", e.getMessage(), e);
            return Result.error("获取学生小题分数据失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.4 学生错题
     * 得分率≤100%的题目统计
     */
    @GetMapping("/student/error-questions/{examId}")
    public Result<List<Map<String, Object>>> getStudentErrorQuestions(
            @PathVariable Long examId,
            @RequestParam(required = false) String studentId,
            @RequestParam(required = false, defaultValue = "100") Integer scoreRateThreshold) {
        try {
            if (examId == null || examId <= 0) {
                return Result.error("考试ID不能为空");
            }
            List<Map<String, Object>> data = scoreAnalysisService.calculateStudentErrorQuestions(examId, studentId, scoreRateThreshold);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取学生错题统计失败: {}", e.getMessage(), e);
            return Result.error("获取学生错题统计失败: " + e.getMessage());
        }
    }

    /**
     * 2.3.5 知识点掌握情况
     */
    @GetMapping("/student/knowledge-score/{examId}")
    public Result<List<Map<String, Object>>> getStudentKnowledgeScore(
            @PathVariable Long examId,
            @RequestParam(required = false) String studentId) {
        try {
            if (examId == null || examId <= 0) {
                return Result.error("考试ID不能为空");
            }
            List<Map<String, Object>> data = scoreAnalysisService.calculateStudentKnowledge(examId, studentId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取知识点掌握情况统计失败: {}", e.getMessage(), e);
            return Result.error("获取知识点掌握情况统计失败: " + e.getMessage());
        }
    }

    /**
     *  学生错题列表uuids
     */
    @GetMapping("/student/error-questions/bank/list/{examId}")
    public Result<?> getStudentErrorQuestionsBanks(
            @PathVariable Long examId,
            @RequestParam String studentId) {
        try {
            if (examId == null || examId <= 0) {
                return Result.error("考试ID不能为空");
            }
            List<String> data = scoreAnalysisService.calculateStudentErrorQuestionIds(examId, studentId);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取错题列表失败: {}", e.getMessage(), e);
            return Result.error("获取错题列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取学生作业周/月汇总统计
     */
    @GetMapping("/student/summary")
    public Result<List<Map<String, Object>>> getStudentSummary(
            @RequestParam(required = false) String studentId,
            @RequestParam(defaultValue = "week") String summaryType) {
        try {
            log.info("获取学生作业周/月汇总统计 - studentId: {}, type: {}", studentId, summaryType);
            List<Map<String, Object>> data = scoreAnalysisService.calculateStudentSummary(studentId, summaryType);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取学生作业周/月汇总统计失败: {}", e.getMessage(), e);
            return Result.error("获取学生作业周/月汇总统计失败: " + e.getMessage());
        }
    }




    /**********************************************年级分析********************************************************/


    /**
     * 2.1.1 年级五率对比（周度/月度）
     * 统计不同年级的满分率、优秀率、良好率、及格率和低分率
     */
    @PostMapping("/grade-rates-comparison")
    public Result<List<Map<String, Object>>> getGradeRatesComparison(@RequestBody ScoreAnalysisInput input) {
        try {
            log.info("获取年级五率对比数据 - startTime: {}, endTime: {}, subjectId: {}, gradeId: {}",
                    input.getStartTime(), input.getEndTime(), input.getSubjectId(), input.getGradeId());

            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeRatesComparison(
                    input.getStartTime(), input.getEndTime(), input.getSubjectId(), input.getGradeId(), input.getClassIds());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取年级五率对比数据失败: {}", e.getMessage(), e);
            return Result.error("获取年级五率对比数据失败: " + e.getMessage());
        }
    }

    /**
     * 获取作业提交情况对比 含作业题量
     * 返回年级及各班级每天的作业提交率
     */
    @GetMapping("/homework-submit-comparison")
    public Result<List<ExamSubmitRateVo>> getHomeworkSubmitComparison(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endTime,
            @RequestParam Long subjectId,
            @RequestParam List<Long> classIds,
            @RequestParam Long gradeId) {
        try {
            log.info("获取作业提交情况对比 - startTime: {}, endTime: {}, subjectId: {}, gradeId: {}",
                    startTime, endTime, subjectId, gradeId);
            List<ExamSubmitRateVo> data = scoreAnalysisService.calculateHomeworkSubmitComparison(
                    startTime, endTime, subjectId, gradeId, classIds);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取作业提交情况对比失败: {}", e.getMessage(), e);
            return Result.error("获取作业提交情况对比失败: " + e.getMessage());
        }
    }


    /**
     * 年级各班级知识点得分率（低于40%标红）
     */
    @GetMapping("/grade-knowledge-score-rates")
    public Result<?> getGradeKnowledgeScoreRates(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endTime,
            @RequestParam Long subjectId,
            @RequestParam List<Long> classIds,
            @RequestParam Long gradeId) {
        try {
            log.info("获取作业提交情况对比 - startTime: {}, endTime: {}, subjectId: {}, gradeId: {}",
                    startTime, endTime, subjectId, gradeId);
            List<KnowledgeScoreRateVo> data = scoreAnalysisService.calculateGradeKnowledgeScoreRates(startTime, endTime, subjectId, gradeId, classIds);
            log.info("知识点得分率数据计算完成，共 {} 条记录", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取知识点得分率失败: {}", e.getMessage(), e);
            return Result.error("获取知识点得分率失败: " + e.getMessage());
        }
    }


    /**
     * 年级各科高频错题（低于40%可设置）
     * 得分率≤40%的题目统计
     */
    @GetMapping("/grade-error-questions")
    public Result<?> getGradeErrorQuestions(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endTime,
            @RequestParam Long subjectId,
            @RequestParam Long gradeId,
            @RequestParam List<Long> classIds,
            @RequestParam(required = false, defaultValue = "40") Integer scoreRateThreshold,
            @RequestParam(required = false, defaultValue = "1")  Integer type) {
        try {
            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeErrorQuestions(subjectId, gradeId, scoreRateThreshold, startTime, endTime, classIds, type);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取高频错题统计失败: {}", e.getMessage(), e);
            return Result.error("获取高频错题统计失败: " + e.getMessage());
        }
    }

    /**
     * 知识点改进效果折线图与图表（低于40%标红）
     */
    @GetMapping("/grade-knowledge-score-rates/chart")
    public Result<?> getGradeKnowledgeScoreRatesChart(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endTime,
            @RequestParam Long subjectId,
            @RequestParam List<Long> classIds,
            @RequestParam Long gradeId) {
        try {
            log.info("获取作业提交情况对比 - startTime: {}, endTime: {}, subjectId: {}, gradeId: {}",
                    startTime, endTime, subjectId, gradeId);
            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeKnowledgeScoreRatesChart(startTime, endTime, subjectId, gradeId, classIds);
            log.info("知识点得分率数据计算完成，共 {} 条记录", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取知识点得分率失败: {}", e.getMessage(), e);
            return Result.error("获取知识点得分率失败: " + e.getMessage());
        }
    }


    /**************************************************成绩概览多次************************************************************/

    /**
     * 年级成绩概览表
     * 满分/最高分/平均分/优秀率/及格率/中位数/标准差
     */
    @GetMapping("/grade/overview/{examId}")
    public Result<?> getGradeScoreOverview(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds) {
        try {
            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeScoreOverview(examId, classIds);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取成绩概览失败: {}", e.getMessage(), e);
            return Result.error("获取成绩概览失败: " + e.getMessage());
        }
    }

    /**
     * 原始分成绩及排名
     * 班级/考号/姓名/学科-日期/总分/客观题/主观题等详细信息
     */
    @GetMapping("/grade/score-details/{examId}")
    public Result<List<Map<String, Object>>> getGradeScoreDetails(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds) {
        log.info("接收到作业得分表请求 - examId: {}, classId: {}", examId, classIds);
        try {
            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeScoreDetails(examId, classIds);

            log.info("成功获取作业得分表数据 - 记录数: {}", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取作业得分表失败", e);
            return Result.error("获取作业得分表失败: " + e.getMessage());
        }
    }
    /**
     * 多次下载成绩单
     * 班级/考号/姓名/学科-日期/总分/客观题/主观题等详细信息
     */
    @GetMapping("/grade/score-details/excel/{examId}")
    public Result<?> gradeScoreDetailsExcel(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds) {
        log.info("接收到作业得分表请求 - examId: {}, classId: {}", examId, classIds);
        try {
            ExamBase examBase = examBaseMapper.selectByExamId(examId);
            if(examBase == null) {
                throw new RuntimeException("未找到考试信息");
            }
            ExamDetail examDetail = examDetailMapper.selectByExamId(examId);
            if(examDetail == null) {
                throw new RuntimeException("未找到考试信息");
            }
            // 获取学生提交记录
            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeScoreDetailsExcel(examDetail.getExamId(), classIds);
            String path = scoreAnalysisService.excel(data, examBase, examDetail, null, 1);
            log.info("成功下载得分表Excel :{}", path);
            return Result.success(path);
        } catch (Exception e) {
            log.error("获取作业得分表失败", e);
            return Result.error("获取作业得分表失败: " + e.getMessage());
        }
    }

    /**
     * 分数段分布图表/表格（分段方式默认5分一段可进行修改重新生成
     * @param examId
     * @param segment
     * @return
     */
    @GetMapping("/grade/score-distribution/{examId}")
    public Result<?> getGradeScoreDistribution(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds,
            @RequestParam(defaultValue = "5") Integer segment) {
        try {
            List<Map<String, Object>> data = scoreDistributionService.calculateGradeScoreDistribution(examId, segment, classIds);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取分数段分布失败: {}", e.getMessage(), e);
            return Result.error("获取分数段分布失败: " + e.getMessage());
        }
    }

    /**
     *  年级两分五率
     */
    @PostMapping("/grade/score-rates")
    public Result<?> getGradeScoreRates(@RequestBody ScoreAnalysisInput input) {
        try {

            List<Map<String, Object>> data = scoreDistributionService.calculateGradeScoreRates(input.getExamId(), input.getClassIds(), input.getGradeId(), input.getSubjectId());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取两分五率失败: {}", e.getMessage(), e);
            return Result.error("获取两分五率失败: " + e.getMessage());
        }
    }

    /**
     *  提交率/空白率对比
     */
    @GetMapping("/grade/student-submit/{examId}")
    public Result<?> getGradeStudentSubmit(
            @RequestParam List<Long> classIds,
            @PathVariable Long examId) {
        try {
            List<Map<String, Object>> data = scoreDistributionService.calculateGradeStudentSubmits(examId, classIds);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取提交率失败: {}", e.getMessage(), e);
            return Result.error("获取提交率失败: " + e.getMessage());
        }
    }

    /**
     * 年级学优生-学困生
     * @param examId
     * @param classIds
     * @return
     */
    @GetMapping("/grade/student-distribution/{examId}")
    public Result<?> getGradeStudentDistribution(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds) {
        try {
            List<Map<String, Object>> data = scoreDistributionService.calculateGradeStudentDistribution(examId, classIds);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取学生分布失败: {}", e.getMessage(), e);
            return Result.error("获取学生分布失败: " + e.getMessage());
        }
    }

    /**
     * 年级获取作业质量
     */
    @GetMapping("/grade/homework-quality/{examId}")
    public Result<?> getGradeHomeworkQuality(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds) {
        try {
            log.info("获取作业质量数据 - examId: {}, classIds: {}", examId, classIds);
            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeHomeworkQuality(examId, classIds);
            log.info("作业质量数据计算完成: {}", data);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取作业质量失败: {}", e.getMessage(), e);
            return Result.error("获取作业质量失败: " + e.getMessage());
        }
    }

    /**
     * 年级试题得分率
     */
    @GetMapping("/grade/question-score-rates/{examId}")
    public Result<?> getGradeQuestionScoreRates(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds) {
        try {
            log.info("获取试题得分率数据 - examId: {}, classId: {}", examId, classIds);
            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeQuestionScoreRates(examId, classIds);
            log.info("试题得分率数据计算完成，共 {} 条记录", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取试题得分率失败: {}", e.getMessage(), e);
            return Result.error("获取试题得分率失败: " + e.getMessage());
        }
    }

    /**
     * 年级知识点得分率
     */
    @GetMapping("/grade/knowledge-score-rates/{examId}")
    public Result<?> getGradeKnowledgeScoreRates(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds) {
        try {
            log.info("获取知识点得分率数据 - examId: {}, classId: {}", examId, classIds);
            List<Map<String, Object>> data = scoreAnalysisService.calculateKnowledgeScoreRatesByGrade(examId, classIds);
            log.info("知识点得分率数据计算完成，共 {} 条记录", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取知识点得分率失败: {}", e.getMessage(), e);
            return Result.error("获取知识点得分率失败: " + e.getMessage());
        }
    }

    /**
     * 年级小题分析
     */
    @GetMapping("/grade/question-analysis/{examId}")
    public Result<?> getGradeQuestionAnalysis(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds) {
        try {
            log.info("获取小题分析数据 - examId: {}, classId: {}", examId, classIds);
            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeQuestionAnalysis(examId, classIds);
            log.info("小题分析数据计算完成，共 {} 条记录", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取小题分析失败: {}", e.getMessage(), e);
            return Result.error("获取小题分析失败: " + e.getMessage());
        }
    }

    /**
     * 年级客观题作答分布
     */
    @GetMapping("/grade/objective-answer-distribution/{examId}")
    public Result<?> getObjectiveAnswerDistribution(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds) {
        try {
            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeObjectiveAnswerDistribution(examId, classIds);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取客观题作答分布失败: {}", e.getMessage(), e);
            return Result.error("获取客观题作答分布失败: " + e.getMessage());
        }
    }

    /**
     * 年级主观题作答分布
     */
    @GetMapping("/grade/subjective-answer-distribution/{examId}")
    public Result<?> getSubjectiveAnswerDistribution(
            @PathVariable Long examId,
            @RequestParam List<Long> classIds) {
        try {
            List<Map<String, Object>> data = scoreAnalysisService.calculateGradeSubjectiveAnswerDistribution(examId, classIds);
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取主观题作答分布失败: {}", e.getMessage(), e);
            return Result.error("获取主观题作答分布失败: " + e.getMessage());
        }
    }


}
